Docker Hub Mysql官方镜像实现首次启动后初始化库表
概述
在Docker Hub中查看MySQL官方镜像的Dockerfile:
COPY docker-entrypoint.sh /usr/local/bin/
RUN ln -s usr/local/bin/docker-entrypoint.sh /entrypoint.sh # backwards compat
ENTRYPOINT ["docker-entrypoint.sh"]
镜像启动时,会运行entrypoint.sh
脚本,该脚本的shell命令中:
echo
for f in /docker-entrypoint-initdb.d/*; do
case "$f" in
*.sh) echo "$0: running $f"; . "$f" ;;
*.sql) echo "$0: running $f"; "${mysql[@]}" < "$f"; echo ;;
*.sql.gz) echo "$0: running $f"; gunzip -c "$f" | "${mysql[@]}"; echo ;;
*) echo "$0: ignoring $f" ;;
esac
echo
done
上述shell命令会遍历/docker-entrypoint-initdb.d/
文件中的sh文件,sql文件,sql.gz压缩包,随后按照sh>sql>sql.gz的顺序依次执行。当该文件夹只存在一种文件时,便会按照文件名排序后执行。
实现首次启动后初始化库表
创建mysql_data文件夹,将data.sql放入:
-- 创建数据库
DROP database IF EXISTS `docker_database`;
create database `docker_database` default character set utf8 collate utf8_general_ci;
-- 切换到test_data数据库
use docker_database;
-- 建表
DROP TABLE IF EXISTS `person`;
CREATE TABLE `person` (
`id` bigint(20) NOT NULL,
`name` varchar(255) DEFAULT NULL,
`age` bigint(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- 插入数据
INSERT INTO `user` (`id`,`name`,`age` )
VALUES
(0,'Tom',18);
启动容器
$ docker run --name test -v /home/master/mysql_data:/docker-entrypoint-initdb.d -d -e MYSQL_ROOT_PASSWORD=123456 mysql
进入容器进行验证
$ docker exec -it sql /bin/bash
root@6da21b87a0a5:/# mysql -u root -p
Enter password:
mysql> use docker_database;
mysql> show tables;
+---------------------------+
| Tables_in_docker_database |
+---------------------------+
| person |
+---------------------------+
1 row in set (0.00 sec)
mysql> select * from person;
+----+------+------+
| id | name | age |
+----+------+------+
| 0 | Tom | 18 |
+----+------+------+
1 row in set (0.00 sec)
mysql> insert into person(id ,name ,age)values(1,'Jane',17);
Query OK, 1 row affected (0.06 sec)
mysql> select * from person;
+----+------+------+
| id | name | age |
+----+------+------+
| 0 | Tom | 18 |
| 1 | Jane | 17 |
+----+------+------+
2 rows in set (0.00 sec)
重启该容器后,数据依然存在。但启动一个新容器后,该容器数据依然为初始状态。
指定sql文件运行顺序
entrypoint.sh
脚本执行sql文件的顺序是按照文件名排序的,这可能导致一些文件执行顺序不符合预期,从而出现错误。例如预期是数据库创建后,再执行表格创建,最后插入数据,而因为文件名,可能数据库先创建后,插入数据,最后创建表格,从而使得数据插入失败。要解决该问题有如下几种方法:
- 将文件按照预期顺序,进行命名,比如1_xx,2_xx;
- 将必须有前后顺序的sql文件合并在一个sql文件中;
- 将sql文件单独放在一个文件夹如data_mysql,将指定sql文件执行顺序的shell脚本放在shell_mysql文件中。容器启动时,将shell_mysql映射到docker-entrypoint-initdb.d文件夹,data_mysql映射到容器内其他文件夹。
假设:data_mysql文件夹存放三个sql文件: database.sql,table.sql,data.sql,shell_mysql存放data.sh
#!/bin/bash
mysql -uroot -p$MYSQL_ROOT_PASSWORD <<EOF
source /usr/local/work/database.sql;
source /usr/local/work/table.sql;
source /usr/local/work/data.sql;
启动容器:
$ docker run --name test -e WORK_PATH=/usr/local/work -e MYSQL_ROOT_PASSWORD=123456 -v /home/master/shell_mysql:/docker-entrypoint-initdb.d -v /home/master/data_mysql:/usr/local/work mysql
数据结果应与上述一致。
This blog is under a CC BY-NC-SA 3.0 Unported License
本文链接:http://yov.oschina.io/article/容器/Docker/Docker Hub mysql官方镜像实现首次启动后初始化库表/